import { useState, useEffect, useImperativeHandle, Key, useMemo } from 'react';
import { Modal, Switch, Input, Form, message, Typography, Tree, Space } from 'antd';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { cloneDeep } from 'lodash';
import { getMessage, TextWidget } from '@inbiz/react';
import { getApp, InbizIcon, uuid } from '@inbiz/utils';
import { ExclamationCircleFilled } from '@ant-design/icons';
// import MultilingualInput from '@inbiz/basic/MultilingualInput';
import { addGroupEntity, deleteProcessGroupById, getProcessGroupList, SortProcessGroup } from '../servers';

const { DirectoryTree } = Tree;

// 左侧分组列表内容区组件
interface IProps {
  activeGroupId: any;
  $activeGroupId: (id: string) => void;
  activeGroupInfo: any;
  $activeGroupInfo: (info: any) => void;
  listData: any[];
  treeData: any[];
  $treeData: (arr: any) => void;
  $listData: (arr: any) => void;
  ScopeProcess: 'all' | 'app' | 'group';
  $rowData: (arr: any) => void;
  getList: () => void;
  addGroupRef: any;
}
const { Text } = Typography;

const LeftList = (props: IProps) => {
  /**
   * activeGroupId: 父组件传下的当前选中分组名称id、修改当前选中分组id的方法
   * listData: 父组件传下的左侧列表数据
   */
  const { activeGroupId, $activeGroupId, $activeGroupInfo, $rowData, listData, treeData, $treeData, getList, $listData, addGroupRef } = props;

  // 初始化表单form对象
  const [form] = Form.useForm();

  // 添加分组弹窗显示
  const [addGroupVisible, $addGroupVisible] = useState<boolean>(false);

  // 是否编辑
  const [isEdit, $isEdit] = useState<boolean>(false);

  // 修改当前分组数据
  const [editGroupNameInfo, $editGroupNameInfo] = useState<any>(null);

  const globalAppInfo = getApp();

  useImperativeHandle(addGroupRef, () => ({
    add: onAdd
  }), [])

  // 监听打开弹窗时回填表单数据
  useEffect(() => {
    if (addGroupVisible) {
      // 先清空
      $isEdit((pre: boolean) => {
        if (pre) {
          form.setFieldsValue({
            groupName: editGroupNameInfo?.groupName,
            mark: editGroupNameInfo?.mark,
            isShow: editGroupNameInfo?.isShow == 1 ? false : true,
          });
        } else {
          form.setFieldsValue({
            groupName: '',
            mark: uuid(20, 70),
            isShow: true,
          });
        }
        return pre;
      });
    }
  }, [addGroupVisible, editGroupNameInfo]);

  // 点击编辑按钮
  const onEdit = (item: any) => {
    //先展示弹窗
    $addGroupVisible(true);
    // 走编辑的逻辑
    $isEdit(true);
    // 将当前选中项的item存起来
    $editGroupNameInfo(item);
  };
  // 点击添加按钮
  const onAdd = () => {
    // 清空一下
    $isEdit(false);
    $editGroupNameInfo(null);
    $addGroupVisible(true);
  };

  // 添加/修改分组名称
  const editGroupName = () => {
    form.validateFields().then((res: any) => {
      let params: any = {};
      if (isEdit) {
        params = editGroupNameInfo;
      }
      params.mark = res?.mark?.trim();
      params.groupName = res.groupName.trim();
      params.isShow = res?.isShow ? 0 : 1;
      params.appId = nowAppId || editGroupNameInfo?.appId || globalAppInfo.AppId;

      try {
        if (listData?.length > 200) {
          message.error('ProcessManage.group_amount_limit');
        } else {
          addGroupEntity(params).then((res: any) => {
            if (res.code == '200') {
              message.success(
                getMessage(
                  isEdit
                    ? 'ProcessManage.edit_group_success'
                    : 'ProcessManage.add_group_success',
                ),
              );
              $addGroupVisible(false);
              if (props.ScopeProcess == 'all') {
                // 全部 - 树节点
                onLoadData({ key: nowAppId || editGroupNameInfo?.appId || globalAppInfo.AppId, Children: false }, !activeGroupId, res.details)
              } else {
                // 部分 - 列表
                getList();
              }
              $nowAppId('')
            } else {
              message.error(res.message);
            }
          });
        }
      } catch (err) { }
    });
  };
  // 关闭增改弹窗
  const closePopup = () => {
    $addGroupVisible(false);
    form.resetFields();
    // 关闭之后
  };
  // 删除当前分组(点哪个用哪个id,调用删除接口，重新拉取列表)

  // 删除弹出框
  const { confirm } = Modal;

  const showConfirm = (groupId: string, appId?: string) => {
    confirm({
      title: getMessage('ProcessManage.define_delete_group'),
      // @ts-ignore
      icon: <ExclamationCircleFilled />,
      centered: true,
      okText: getMessage('ProcessManage.define'),
      cancelText: getMessage('ProcessManage.cancelText'),
      onOk() {
        deleteItem(groupId, appId);
      },
      onCancel() { },
    });
  };

  const deleteItem = async (groupId: string, appId?: string) => {
    try {
      const res = await deleteProcessGroupById({ groupId });
      if (res.code == '200') {
        message.success(res.message);
        if (appId) {
          // 全部 - 树节点
          onLoadData({ key: appId, Children: false }, activeGroupId == groupId)
        } else {
          // 部分 - 列表
          getList();
          if (listData.filter((item: any) => item.id != groupId).length == 0) {
            $activeGroupId('')
            $activeGroupInfo(null)
          } else {
            if ((groupId == activeGroupId || (activeGroupId == listData[0].id))) {
              $activeGroupId(listData[0].id);
              $activeGroupInfo(listData[0])
            }
          }
        }
      } else {
        message.error(res.message);
      }
    } catch (err) { }
  };

  // 拖动排序
  const onSortEnd = async ({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {
    if (oldIndex !== newIndex) {
      let oldSort = listData[oldIndex].sort;
      let newSort = listData[newIndex].sort;
      const oldListData = cloneDeep(listData);
      const arr = move(listData, oldIndex, newIndex);
      arr.forEach((item: any, idx: number) => {
        item.sort = idx;
      });
      $listData(arr);
      SortProcessGroup({
        direction: oldSort > newSort ? 'up' : 'down',
        newIndex: newSort,
        oldIndex: oldSort,
      }).then((res: any) => {
        // getList()
        if (res.code != '200') {
          // 还原
          $listData(oldListData);
        }
      });
    }
  };
  /**
   * 拖拽后位置置换
   * @param array any[] 原数据数组
   * @param fromIndex number 原数据位置
   * @param toIndex number 新数据位置
   * @returns
   */
  const move = (array: any[], fromIndex: number, toIndex: number) => {
    const newArray = [...array];
    const startIndex = fromIndex < 0 ? newArray?.length + fromIndex : fromIndex;
    if (startIndex >= 0 && startIndex < newArray?.length) {
      const endIndex = toIndex < 0 ? newArray?.length + toIndex : toIndex;
      const [item] = newArray.splice(fromIndex, 1);
      newArray.splice(endIndex, 0, item);
    }
    return newArray;
  };

  // 当前添加所在的appId
  const [nowAppId, $nowAppId] = useState<string>('')
  // 分组树已展开的节点
  const [expandedKeys, $expandedKeys] = useState<string[]>([]);

  // 分组树单项节点Dom
  const TreeNode = (rec: any, app: boolean) => {
    return (
      <div className='custon-tree-node'>
        <span title={getMessage(app ? rec.AppName : rec.groupName)} className={rec.isShow == 1 ? 'hide-group' : ''}>
          <TextWidget>{app ? rec.AppName : rec.groupName}</TextWidget>
        </span>
        <Space className='tree-node-hand' onClick={(e) => { e.stopPropagation() }}>
          {
            app ?
              // 添加
              <InbizIcon
                type="icon-ic-add-bold"
                onClick={() => { $nowAppId(rec.id); onAdd() }}
              />
              : <>
                {/* 修改 */}
                <InbizIcon
                  type="icon-ic-bianjituandui"
                  onClick={() => { onEdit(rec) }}
                />
                {/* 删除 */}
                <InbizIcon
                  className='del'
                  type="icon-ic-shanchu1"
                  onClick={() => { showConfirm(rec.id, rec.appId) }}
                />
              </>
          }
        </Space>
      </div>
    )
  }

  // 自动计算后的tree数据
  const treeDom = useMemo(() => {
    // 如果没有选中分组且第一个应用下有分组的话则展开第一个应用
    if (!expandedKeys?.length && treeData?.[0]?.Children?.length) {
      $expandedKeys([treeData[0].id])
    }
    return treeData.map((item: any) => {
      const i = {
        ...item,
        title: TreeNode(item, true)
      }
      if (i.Children?.length) {
        i.Children = i.Children.map((val: any) => {
          return {
            ...val,
            isLeaf: true,
            title: TreeNode(val, false),
          }
        })
      }
      return i
    })
  }, [treeData, activeGroupId])

  // 树展开节点变化
  const onExpand = (keys: string[]) => {
    $expandedKeys(keys);
  };

  // 异步加载树节点的子节点(获取指定应用下分组列表)
  const onLoadData = ({ key, Children }: any, pick?: boolean, pickId?: string) => {
    return new Promise<void>(async (resolve) => {
      const selGroup = (nowGroup: any) => {
        if (pick) {
          // 重选当前分组
          if (Array.isArray(nowGroup?.details?.rows) && nowGroup.details.rows.length) {
            if (pickId) {
              // 当前无选中时-选中当前新建或编辑的分组
              $activeGroupId(pickId)
              const record = nowGroup.details.rows.find((v: any) => v.id == pickId)
              $activeGroupInfo(record)
            } else {
              // 当前无选中时-选中第一个(删除分组为选中分组时)
              $activeGroupId(nowGroup.details.rows[0]?.id)
              $activeGroupInfo(nowGroup.details.rows[0])
            }
          } else {
            $activeGroupId('')
            $activeGroupInfo(null)
          }
        }
        // 添加分组时如果该父级未展开则展开父节点
        if (pickId) {
          $expandedKeys((pre: any[]) => {
            if (pre.includes(key)) {
              return pre
            } else {
              return [...pre, key]
            }
          })
        }
      }
      if (Children) {
        selGroup(Children)
        resolve();
        return;
      }
      const nowGroup: any = await getProcessGroupList({ pageSize: 9999, appId: key })

      const tree = treeData.map((i: any) => {
        if (i.id == key) {
          selGroup(nowGroup)
          if (Array.isArray(nowGroup?.details?.rows) && nowGroup.details.rows.length) {
            return { ...i, Children: nowGroup.details.rows }
          } else {
            return { ...i, Children: [] }
          }
        }
        return i
      })
      $treeData(tree)
      resolve();
    });
  }

  // 全局-树节点点击
  const clickGroup = (key: any, rec: any) => {
    if (!rec?.node?.app) {
      $activeGroupId(key)
      $activeGroupInfo(rec.node)
    }
  }

  return (
    <>
      <div className="left-list">
        {
          props.ScopeProcess !== 'all' ? <>
            <div className="processGroup">
              <span>
                &nbsp;
                <TextWidget>ProcessManage.process_group</TextWidget>
              </span>
              {props.ScopeProcess !== 'group' && (
                <div className="add-btn" onClick={onAdd}>
                  <span>
                    <InbizIcon type="icon-ic-tianjia-moren" />
                  </span>
                  <span style={{ marginLeft: '8px' }}>
                    <TextWidget>ProcessManage.add</TextWidget>
                  </span>
                </div>
              )}
            </div>
            {/* 列表 */}
            <SortableList
              list={listData}
              lockAxis="y"
              onSortEnd={onSortEnd}
              useDragHandle
              activeGroupId={activeGroupId}
              $activeGroupId={$activeGroupId}
              $activeGroupInfo={$activeGroupInfo}
              $rowData={$rowData}
              onEdit={onEdit}
              showConfirm={showConfirm}
            />
          </> :
            <DirectoryTree
              showIcon={false}
              fieldNames={{
                key: 'id',
                children: 'Children',
              }}
              expandedKeys={expandedKeys}
              onExpand={onExpand}
              loadData={onLoadData}
              onSelect={(keys: Key[], e: any) => clickGroup(keys?.[0] || '', e)}
              selectedKeys={activeGroupId !== '' ? [activeGroupId] : []}
              treeData={treeDom}
            />
        }

        {/* 添加弹窗*/}
        {addGroupVisible && (
          <Modal
            title={
              editGroupNameInfo
                ? getMessage('ProcessManage.edit_group')
                : getMessage('ProcessManage.add_group')
            }
            visible={addGroupVisible}
            width={500}
            onCancel={closePopup}
            onOk={editGroupName}
            okText={getMessage('ProcessManage.define')}
            cancelText={getMessage('ProcessManage.cancelText')}
            centered={true}
            destroyOnClose
          >
            <Form
              form={form}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 17 }}
              colon={false}
              labelAlign="right"
            >

              {/* 分组名称 */}
              <Form.Item
                name="groupName"
                label={
                  <Text ellipsis={{ tooltip: getMessage('ProcessManage.add_group_name') }}>
                    {getMessage('ProcessManage.add_group_name')}
                  </Text>
                }
                required
                rules={[
                  ({ }) => ({
                    validator(_, value): any {
                      if (!value || value?.trim?.() == '') {
                        return Promise.reject(new Error(getMessage('ProcessManage.enter_group_name')))
                      } else if (value.length > 50) {
                        return Promise.reject(getMessage('ProcessManage.limit_group_length'))
                      } else if (/^[\u4E00-\u9FA5A-Za-z0-9\_\-\——\'\(\)\。\、\【\】\‘\’\“\”\《\》\……\（\）\s]+$/.test(value)) {
                        return Promise.resolve()
                      }
                      return Promise.reject(getMessage('ProcessManage.special_character'))
                    },
                  }),
                ]}
              >
                <Input
                  placeholder={getMessage('ProcessManage.placeMessage')}
                  disabled={editGroupNameInfo?.groupName == '默认流程' ? true : false}
                />
              </Form.Item>

              {/* 分组标识 */}
              <Form.Item
                name="mark"
                label={getMessage('ProcessManage.add_group_key')}
                rules={[
                  { required: true, message: getMessage('ProcessManage.group_mark_required') },
                  { max: 200, message: getMessage('ProcessManage.group_mark_limit') },
                  {
                    pattern: /^[A-Za-z0-9_]+$/,
                    message: getMessage('ProcessManage.group_mark_pattern'),
                  },
                ]}
              >
                <Input placeholder={getMessage('ProcessManage.mark_tip')} />
              </Form.Item>

              {/* 是否可见 */}
              <Form.Item
                name="isShow"
                valuePropName="checked"
                label={
                  <Text ellipsis={{ tooltip: getMessage('ProcessManage.isVisible') }}>
                    {getMessage('ProcessManage.isVisible')}
                  </Text>
                }
              >
                <Switch />
              </Form.Item>
            </Form>
          </Modal>
        )}
      </div>
    </>
  );
};

export default LeftList;

const DragHandle: any = SortableHandle(() => (
  <InbizIcon type="icon-inbiz_other-drag" style={{ cursor: 'grab' }} />
));

// 拖拽每项
const SortableItem: any = SortableElement((props: any) => {
  return (
    <div
      className={
        props.item.id === props.activeGroupId
          ? 'process-management-group-list-sort-item active'
          : 'process-management-group-list-sort-item'
      }
    >
      <span
        className="item-name"
        onClick={() => {
          props.$rowData([]);
          props?.$activeGroupId?.(props.item.id);
          props?.$activeGroupInfo?.(props.item);
        }}
        style={props.item.isShow == 1 ? { color: '#ccc' } : {}}
        title={getMessage(props.item.groupName)}
      >
        <TextWidget>{props.item.groupName}</TextWidget>
      </span>
      <span className="item-handle">
        <InbizIcon
          type="icon-ic-bianjituandui"
          // title={getMessage('ProcessManage.edit_process')}
          onClick={() => props.onEdit(props.item)}
        />
        {props?.item?.id !== '1' && (
          <>
            <InbizIcon
              type="icon-ic-shanchu1"
              // title={getMessage('ProcessManage.delText')}
              onClick={() => props.showConfirm(props.item.groupId)}
            />
          </>
        )}
        <DragHandle />
      </span>
    </div>
  );
});

// 拖拽列表
const SortableList: any = SortableContainer(
  (props: {
    list: any[];
    activeGroupId: any;
    onEdit: any;
    showConfirm: any;
    $activeGroupId: (id: string) => void;
    $activeGroupInfo: (info: any) => void;
    $rowData: (arr: []) => void;
  }) => {
    return (
      <div className="process-management-group-list">
        {props.list?.map((item: any, idx: number) => {
          return <SortableItem item={item} key={item.id} index={idx} {...props} />;
        })}
      </div>
    );
  },
);
